package com.liyujie.networkrequest.utils.serialport;


import com.blankj.utilcode.util.ConvertUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.SPUtils;
import com.liyujie.networkrequest.utils.InitializeUtils;

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

import android_serialport_api.SerialPortFinder;
import tp.xmaihh.serialport.SerialHelper;
import tp.xmaihh.serialport.bean.ComBean;

public class OpenPortUtils {

    private  static  final  Semaphore Mutex =new Semaphore(1,true);

    private static  final Semaphore semaphore=new Semaphore(0,true);
    private static byte[] receiveBuff = null;
    private static SerialPortFinder mSerialPortFinder;
    private static SerialHelper mSerialHelper;
    /**
     * 初始化开门串口
     */
    public static void InitializeTheOpenSerialPort(){
        mSerialPortFinder = new SerialPortFinder();
        mSerialHelper = new SerialHelper(SPUtils.getInstance().getString("OpenSerialPort","/dev/ttyS4"), 9600) {
            @Override
            protected void onDataReceived(ComBean comBean) {
                if(null != comBean && null != comBean.bRec && comBean.bRec.length > 0){
                    receiveBuff = new byte[comBean.bRec.length];
                    System.arraycopy(comBean.bRec,0,receiveBuff,0,comBean.bRec.length);
                    semaphore.release();
//                    String mSwipeCard = CommonUtils.bytesToHex(comBean.bRec);
//                    System.out.println("内容" + mSwipeCard);
                }
            }
        };
        mSerialHelper.setDataBits(8);//数据位
        mSerialHelper.setParity(0);//校验位
        mSerialHelper.setStopBits(1);//停止位
        mSerialHelper.setFlowCon(0);//流控
        mSerialHelper.setiDelay(1000);
        try {
            mSerialHelper.open();//开启串口
            InitializeUtils.getDefaultMaker().show("开门串口开启成功" + mSerialHelper.getPort());
        }catch (Exception e){
            System.out.println(e.getMessage());
        }

    }

    /**
     * 获得所有串口设备的地址
     * @return
     */
    public static String[] getAllDeicesPath(){
        if(null != mSerialPortFinder){
            return mSerialPortFinder.getAllDevicesPath();
        }else {
            mSerialPortFinder = new SerialPortFinder();
            return mSerialPortFinder.getAllDevicesPath();
        }
    }


    /**
     * 设置主锁板
     * @param door
     * @param cmd 0开门  1是开始编号  2是结束编号 3 查询门状态
     */
    public static boolean sendData(int door, String cmd){
        byte[] sendContentBytes = new byte[6];
        sendContentBytes[0] = (byte) door; //设备地址
        sendContentBytes[1] =  Byte.valueOf(cmd);//命令
        sendContentBytes[2] = 1; //桢序列
        sendContentBytes[3] = 1;////数据长度
        sendContentBytes[4] = (byte) door; //数据在和
        sendContentBytes[5] =(byte)( 0 - sendContentBytes[0] - sendContentBytes[1] - sendContentBytes[2] - sendContentBytes[3] - sendContentBytes[4]); //校验
        if(null != mSerialHelper){
            LogUtils.d("Tx" + ConvertUtils.bytes2HexString(sendContentBytes));
            mSerialHelper.send(sendContentBytes);
            return true;
        }else {
            return false;
        }
    }


    /**
     * 开门，且自动重发
     * @param event
     * @return  返回串口收到的正确结果
     */
    public static boolean openDoor(int event){
        boolean Senddata = false;
        try {
            if(Mutex.tryAcquire(5,TimeUnit.MINUTES)) {
                byte[] sendContentBytes = new byte[6];
                sendContentBytes[0] = (byte) event; //设备地址
                sendContentBytes[1] = 0;//命令
                sendContentBytes[2] = 1; //桢序列
                sendContentBytes[3] = 1;////数据长度
                sendContentBytes[4] = (byte) event; //数据在和
                sendContentBytes[5] = (byte) (0 - sendContentBytes[0] - sendContentBytes[1] - sendContentBytes[2] - sendContentBytes[3] - sendContentBytes[4]); //校验
                int cnt = 2;  //定义重发次数
                if (null != mSerialHelper) {
                    try {
                        do {
                            receiveBuff = null;
                            while (semaphore.tryAcquire()) ;
                            //发送开门命令
                            mSerialHelper.send(sendContentBytes);
                            System.out.println("Tx" + ConvertUtils.bytes2HexString(sendContentBytes));
                            //从queue中获取串口收到的数据
                            if (semaphore.tryAcquire(800, TimeUnit.MILLISECONDS)) {
                                System.out.println("wait success" + ConvertUtils.bytes2HexString(receiveBuff));
                                if (receiveBuff != null) {
                                    byte sum = 0;
                                    if ((sum == 0 && receiveBuff.length == 7) || (receiveBuff[0] == event && receiveBuff.length == 1)) {
                                        Senddata = true;
                                        break;
                                    } else {
                                        semaphore.tryAcquire(300, TimeUnit.MILLISECONDS);//收到消息不对，延时300ms重发
                                    }
                                } else {
                                    System.out.println("receiveBuffBuff is null");
                                    semaphore.tryAcquire(300, TimeUnit.MILLISECONDS);//收到消息不对，延时300ms重发
                                }
                            } else {
                                System.out.println("wait semaphore time out");
                            }
                            //否则重发数据
                            cnt--;
                        } while (cnt > 0);
                    } catch (Exception exception) {

                    }
                }
                Mutex.release();
            }
        }catch (Exception e){
           LogUtils.e(e.getMessage());
        }
        return Senddata;
    }




    /**
     * 获取反馈
     * @return
     */
    public static byte[] gainFeedback(int door) {
        try {
            if (Mutex.tryAcquire(5, TimeUnit.MINUTES)) {
                byte[] sendContentBytes = new byte[6];
                sendContentBytes[0] = (byte) door; //设备地址
                sendContentBytes[1] = 3;//命令
                sendContentBytes[2] = 1; //桢序列
                sendContentBytes[3] = 1;////数据长度
                sendContentBytes[4] = (byte) door; //数据在和
                sendContentBytes[5] = (byte) (0 - sendContentBytes[0] - sendContentBytes[1] - sendContentBytes[2] - sendContentBytes[3] - sendContentBytes[4]); //校验
                int cnt = 1;  //定义重发次数
                if (mSerialHelper != null) {
                    try {
                        do {
                            receiveBuff = null;
                            while (semaphore.tryAcquire()) ;
                            //发送开门命令
                            mSerialHelper.send(sendContentBytes);
                            System.out.println("Tx" + ConvertUtils.bytes2HexString(sendContentBytes));
                            if (semaphore.tryAcquire(800, TimeUnit.MILLISECONDS)) {
                                System.out.println("wait success" + ConvertUtils.bytes2HexString(receiveBuff));
                                if (receiveBuff != null) {
                                    if (receiveBuff.length > 3) {
                                        break;
                                    } else {
                                        semaphore.tryAcquire(300, TimeUnit.MILLISECONDS);//收到消息不对，延时300ms重发
                                    }
                                } else {
                                    System.out.println("receiveBuffBuff is null");
                                    semaphore.tryAcquire(300, TimeUnit.MILLISECONDS);//收到消息不对，延时300ms重发
                                }
                            } else {
                                System.out.println("wait semaphore time out");
                            }
                            //否则重发数据
                            cnt--;
                        } while (cnt > 0);
                    } catch (Exception exception) {
                        return null;
                    }
                }
                Mutex.release();
                return receiveBuff;
            }
        }catch (Exception e){
            LogUtils.e(e.getMessage());
        }
        return null;
    }
}
